#include "exception.hpp"

inline unsigned int __strlen(const char * string)
{
    unsigned int res(0);
    const char * ptr(string);
    for(; (ptr && ((*ptr)) != '\0') ; ptr++)
        res++;
    return res;
}

inline void __strcpy(char * destination, const char * source)
{
    const char * src(source);
    char       * dst(destination);

    for(; ((*src) != '\0') ;)
        *(dst++) = *(src++);
    *(dst) = *(src);
}

inline void __strcat(char * destination, const char * source)
{
    unsigned int n(0), t1(__strlen(destination)), t2(__strlen(source));
    char       * res = new char[t1+t2+1];
    const char * src2(source);
    char       * src1(destination), * dst(res);

    for( ; n<t1 ; n++)
        *(dst++) = *(src1++);
    for(n=0 ; n<=t2 ; n++)
        *(dst++) = *(src2++);
    delete [] destination;
    destination = res;
}

//all descriptions have been done in the header file, only tips have been written here.

// NOTICE  that all (char *) attributes are always allocated excepted the attribute objt, which are displayed only if it's being used.

inline void Exception::__delete()
{
    if(name) delete [] name;
    if(func) delete [] func;
    if(file) delete [] file;
}

//Put attributes name, func, file as "unknown" and the attributes objt (char *) as NULL, line (int) at 0.
Exception::Exception() :
    name(new char[13]), func(new char[13]), file(new char[13]), line(0)
{
    __strcpy(name,"unknown name");
    __strcpy(func,"unknown name");
    __strcpy(file,"unknown file");
}

//Free memory for attributes name, objt, func, file (char *). A check is done for name, func, file ( not necessary ).
Exception::~Exception()
{
    __delete();
}

//Copy all attributes in the new object instancied - Allocate new strings, depending of the size of datas.
Exception::Exception(const Exception &exception) :
    name(new char[__strlen(exception.name)]), func(new char[__strlen(exception.func)]), file(new char[__strlen(exception.file)]), line(exception.line)
{
    __strcpy(name,exception.name);
    __strcpy(func,exception.func);
    __strcpy(file,exception.file);
}

//Copy all attributes in the object returned. Free memory of old strings, and allocate new strings, depending of the size of datas.
Exception& Exception::operator=(const Exception &exception)
{
    __delete();

    name = new char[__strlen(exception.name)];
    func = new char[__strlen(exception.func)];
    file = new char[__strlen(exception.file)];

    __strcpy(name,exception.name);
    __strcpy(func,exception.func);
    __strcpy(file,exception.file);

    line=exception.line;

    return *this;
}

// only care of the attribute name
Exception::Exception(const char *_name) :
    name(new char[__strlen(_name)]), func(new char[13]), file(new char[13]), line(0)
{
    __strcpy(name,_name);
    __strcpy(file,"unknown file");
    __strcpy(func,"unknown line");
}

//Put attribute objt (char *) at NULL, but car about the others attributes
Exception::Exception(const char *_name, const char *_func, const char *_file, int _line) :
    name(new char[__strlen(_name)]), func(new char[__strlen(_func)]), file(new char[__strlen(_file)]), line(_line)
{
    __strcpy(name,_name);
    __strcpy(func,_func);
    __strcpy(file,_file);
}

// return file parante
char * Exception::getFile() const { return file; }
// return fonction parante
char * Exception::getFunction() const { return func; }
// return line parante
int Exception::getLine() const { return line; }
// return name parante
char * Exception::what() const { return name; }



